﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SpriteMaker
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (OD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                lstImages.Items.Clear();
                foreach (var filename in OD.FileNames)
                {
                    lstImages.Items.Add(filename);
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Bitmap firstBmp = null;
            try
            {
                int imgCount = lstImages.Items.Count;
                int Col = (int)Math.Sqrt(imgCount);
                int Row = (Col * Col != imgCount) ? Col + 1 : Col;
                if (Col * Row < imgCount) Col++;
                if (Col * Row < imgCount) throw new Exception("Неверный размер изображения");
                firstBmp = new Bitmap(lstImages.Items[0].ToString());
                int OriginalWidth = firstBmp.Width;
                int OriginalHeight = firstBmp.Height;

                int[] variants = {-4,-3,-1, -2, 0, 1, 2,3,4};
                int BigImageWidth=0, BigImageHeight=0;
                int minIndex = 2;
                ulong minValue = ulong.MaxValue;
                for (int i = 0; i < variants.Length; i++)
                {
                    int CurrentCol = Col + variants[i];
                    int CurrentRow = Row - variants[i];
                    if (CurrentRow * CurrentCol < imgCount) continue;
                    BigImageWidth = (CurrentCol) * firstBmp.Width;
                    BigImageWidth = (int) Math.Pow(2, Math.Ceiling(Math.Log(BigImageWidth, 2)));
                    //if (BigImageWidth > 2048) throw new Exception("Ширина изображения превышает 2048");
                    BigImageHeight = (CurrentRow) * firstBmp.Height;
                    BigImageHeight = (int) Math.Pow(2, Math.Ceiling(Math.Log(BigImageHeight, 2)));
                    //if (BigImageHeight > 2048) throw new Exception("Высота изображения превышает 2048");
                    ulong sum = (ulong)BigImageHeight * (ulong)BigImageWidth;
                    if (sum<minValue)
                    {
                        minIndex = i;
                        minValue = sum;
                    }
                }
                Col += variants[minIndex];
                Row -= variants[minIndex];
                BigImageWidth = (Col ) * firstBmp.Width;
                //BigImageWidth = (int)Math.Pow(2, Math.Ceiling(Math.Log(BigImageWidth, 2)));
                BigImageHeight = (Row ) * firstBmp.Height;
                //BigImageHeight = (int)Math.Pow(2, Math.Ceiling(Math.Log(BigImageHeight, 2)));

                firstBmp.Dispose();
                firstBmp = null;
                Bitmap bigImage = new Bitmap(BigImageWidth, BigImageHeight, PixelFormat.Format32bppArgb);
                Graphics gr = Graphics.FromImage(bigImage);
                int x = 0, y = 0;
                for (int i = 0; i < imgCount; i++)
                {
                    string filename = (string)lstImages.Items[i];
                    Bitmap bmp = new Bitmap(filename);
                    gr.DrawImage(bmp, x, y, OriginalWidth, OriginalHeight);
                    x += OriginalWidth;
                    if ((i + 1) % Col == 0)
                    {
                        x = 0;
                        y += OriginalHeight;
                    }
                    bmp.Dispose();
                }
                bigImage.Save(Path.GetDirectoryName(OD.FileName) + @"\sprite.png");
                bigImage.Dispose();

            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
            finally 
            {
                if (firstBmp != null ) firstBmp.Dispose();
                
            }
        }
    }
}
